package flex.cc.order.manage.service.impl;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;

import javax.annotation.Resource;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import flex.cc.PublicUtil;
import flex.cc.base.dto.LoginAuthDto;
import flex.cc.base.exception.BusinessException;
import flex.cc.basicinformation.entity.ChannelDataEntity;
import flex.cc.basicinformation.service.ChannelService;
import flex.cc.common.utils.HttpClientUtil;
import flex.cc.core.utils.RequestUtil;
import flex.cc.order.manage.dao.OrderPushImgDao;
import flex.cc.order.manage.dao.OrderTrackDao;
import flex.cc.order.manage.dto.order.OrderImgEntity;
import flex.cc.order.manage.dto.order.OrderMainEntity;
import flex.cc.order.manage.dto.order.OrderPushImgEntity;
import flex.cc.order.manage.dto.order.OrderTrackEntity;
import flex.cc.order.manage.dto.vo.PushImgReportVo;
import flex.cc.order.manage.service.OrderImgService;
import flex.cc.order.manage.service.OrderMainService;
import flex.cc.order.manage.service.OrderPushImgService;
import flex.cc.util.ExportUtil;

/**
*
* @author WANGCONG
* 2022年3月2日上午10:40:12
* @desc 救援单图片回传记录实现层
*/
@Service("orderPushImgService")
@Transactional(rollbackFor = Exception.class)
public class OrderPushImgServiceImpl extends ServiceImpl<OrderPushImgDao, OrderPushImgEntity> implements OrderPushImgService {

	@Resource
	private OrderPushImgDao orderPushImgDao;
	@Resource
	private OrderMainService orderMainService;
	@Resource
	private OrderImgService orderImgService;
	@Resource
    private OrderTrackDao orderTrackDao;
	/** 回传图片接口参数 */
	public static final String CHANNEL = "ZXHY";
	/** 回传图片接口参数 */
	public static final String KEY = "CSHAPPZX";
	@Value("${pengda.prefix}")
    private String prefix;
	@Value("${pengda.synImg}")
	private String synImg_url;
	@Resource
	private ChannelService channelService;
	
	
	/**
	*
	* @author WANGCONG
	* 2022年3月2日上午10:42:17
	* @desc 分页查询
	*/
	@Override
	public IPage<OrderPushImgEntity> queryListWithPage(OrderPushImgEntity vo) {
		Page<OrderPushImgEntity> page = new Page<>(vo.getPageNum(),vo.getPageSize());
		IPage<OrderPushImgEntity> pageData=orderPushImgDao.queryListWithPage(page, vo);
		return pageData;
	}

	/**
	 * 
	 * @author WANGCONG
	 * 2022年3月2日上午10:45:28
	 * @desc 保存
	 */
	@Override
	public int insert(OrderPushImgEntity vo) {
		return orderPushImgDao.insert(vo);
	}

	/**
	 * 
	 * @author WANGCONG
	 * 2022年3月2日上午10:47:06
	 * @desc 更新
	 */
	@Override
	public int update(OrderPushImgEntity vo) {
		return orderPushImgDao.update(vo);
	}

	/**
	*
	* @author WANGCONG
	* 2022年3月2日下午17:26:18
	* @desc 图片回传模板下载
	*/
	@Override
	public void downLoadTemplate(HttpServletRequest request, HttpServletResponse response, String fileParentPath,
			String fileName) {
		// 表名、表头数据
        String title = fileName;
//        String[] headers = {"救援单号","来源单号"};
//        String[] fields = {"orderNo","ownerOrderNo"};
        String[] headers = {"来源单号"};
        String[] fields = {"ownerOrderNo"};
        List<OrderMainEntity> records = new ArrayList<>();
        try {
            SXSSFWorkbook wb = ExportUtil.createWorkbook(10, false);//创建工作簿对象
            ExportUtil.downLoadMedicalTemplate(title, headers, fields, 0, wb, records);
            File fileParent = new File(fileParentPath);
            if (!fileParent.exists()) { // 若目录不存在则创建
                fileParent.mkdirs();
            }
            File file = new File(fileParentPath + File.separator + fileName + ".xlsx");
            if (file.exists()) { // 若文件已存在则删除
                file.delete();
            }
            try {
                wb.write(new FileOutputStream(file));
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
	}

	/**
	 * 
	 * @author WANGCONG
	 * 2022年3月3日上午10:23:56
	 * @desc 异步图片回传
	 */
	@SuppressWarnings({ "serial", "deprecation" })
	@Override
	@Async
	public void asyncPushImg(String dataId, LoginAuthDto loginUser, List<String> ownerOrderNoList) {
		AtomicReference<Integer> successNumber = new AtomicReference<Integer>(0);
		AtomicReference<Integer> failNumber = new AtomicReference<Integer>(0);
		List<PushImgReportVo> records = new ArrayList<PushImgReportVo>();
		try {
			for(int i=0; i<ownerOrderNoList.size(); i++){
				PushImgReportVo vo = new PushImgReportVo();
				String ownerOrderNo = ownerOrderNoList.get(i);
				OrderMainEntity orderMain =  orderMainService.queryByOwnerOrderNo(ownerOrderNo);
				if(orderMain==null){
					vo.setOrderNo("");
					vo.setOwnerOrderNo(ownerOrderNo);
					vo.setStatus("失败");
					vo.setFailMsg("来源单号不存在");
					records.add(vo);
					failNumber.compareAndSet(failNumber.get(), failNumber.get()+1);
				}else{
					String sourceName = orderMain.getSourceName();
					String orderNo = orderMain.getOrderNo();
					if("00".equals(sourceName)){
						vo.setOrderNo(orderNo);
						vo.setOwnerOrderNo(ownerOrderNo);
						vo.setStatus("失败");
						vo.setFailMsg("自营渠道不支持图片回传");
						records.add(vo);
						failNumber.compareAndSet(failNumber.get(), failNumber.get()+1);
					}else{
						List<OrderImgEntity> imgList = orderImgService.queryImgByOrderNo(orderNo);
						if(imgList==null || imgList.size()==0){
							vo.setOrderNo(orderNo);
							vo.setOwnerOrderNo(ownerOrderNo);
							vo.setStatus("失败");
							vo.setFailMsg("没有图片，无法回传");
							records.add(vo);
							failNumber.compareAndSet(failNumber.get(), failNumber.get()+1);
						}else{
							
							Map<String, String> channelMap = new HashMap<String, String>();
							channelMap.put("clientId", sourceName);
							channelMap.put("urlType", "5"); //图片回传
							ChannelDataEntity channelData = channelService.findChannelDataByParam(channelMap);
							if(PublicUtil.isEmpty(channelData)){
								vo.setOrderNo(orderNo);
								vo.setOwnerOrderNo(ownerOrderNo);
								vo.setStatus("失败");
								vo.setFailMsg("渠道未配置图片回传接口，无法回传");
								records.add(vo);
								failNumber.compareAndSet(failNumber.get(), failNumber.get()+1);
							}else{
								String status = orderMain.getStatus();
								//接口处理
								List<String> picUrls = new ArrayList<String>();
								for(int j=0; j<imgList.size(); j++){
									String url = imgList.get(j).getUrl();
									String localUrl = imgList.get(j).getLocalUrl();
									if(PublicUtil.isNotEmpty(localUrl)){
										picUrls.add(prefix + localUrl);
									}else{
										picUrls.add(url);
									}
								}
								Map<String, Object> params = new HashMap<>();
								params.put("customerCode",ownerOrderNo);
								params.put("caseNo",ownerOrderNo);
								params.put("carServiceType","0");
								params.put("tracktype","");
								params.put("picList", picUrls);
								String cshToken = DESEncrypt(params.get("customerCode") + "_" + System.currentTimeMillis() + "_" + CHANNEL, KEY);
								//String result = "{\"resCode\":\"SUCCESS\",\"resMsg\":\"成功\"}";
								String result = HttpClientUtil.sendHttpPost(synImg_url, JSONObject.toJSONString(params), new HashMap<String, String>(){{
									put("Content-Type", "application/json;charset=utf-8");
									put("cshToken", cshToken);
									put("channel", CHANNEL);
						        }});
								String temp_code = "";
								String temp_msg = "";
								if (result != null) {
									try {
				            			JSONObject resultObj = JSONObject.parseObject(result);
				                        String resCode = PublicUtil.isNotEmpty(resultObj.get("resCode")) ? resultObj.get("resCode").toString() : null; 
				                        if(PublicUtil.isNotEmpty(resCode) && "SUCCESS".equals(resCode)){
				                        	vo.setOrderNo(orderNo);
				    						vo.setOwnerOrderNo(ownerOrderNo);
				    						vo.setStatus("成功");
				    						vo.setFailMsg("");
				    						records.add(vo);
				                        	successNumber.compareAndSet(successNumber.get(), successNumber.get()+1);
				                        	temp_code = resCode;
				                			Thread.sleep(100);
				                        }else{
				                        	vo.setOrderNo(orderNo);
				    						vo.setOwnerOrderNo(ownerOrderNo);
				    						vo.setStatus("失败");
				    						vo.setFailMsg(result);
				    						records.add(vo);
				                        	failNumber.compareAndSet(failNumber.get(), failNumber.get()+1);
				                        	temp_msg = "批量执行图片回传失败："+result;
				                        }
									} catch (Exception e) {
										vo.setOrderNo(orderNo);
										vo.setOwnerOrderNo(ownerOrderNo);
										vo.setStatus("失败");
										vo.setFailMsg("响应报文解析异常");
										records.add(vo);
										failNumber.compareAndSet(failNumber.get(), failNumber.get()+1);
										temp_msg = "批量执行图片回传失败：响应报文解析异常";
									}
								}else {
									vo.setOrderNo(orderNo);
									vo.setOwnerOrderNo(ownerOrderNo);
									vo.setStatus("失败");
									vo.setFailMsg("响应报文为空");
									records.add(vo);
									failNumber.compareAndSet(failNumber.get(), failNumber.get()+1);
									temp_msg = "批量执行图片回传失败：响应报文为空";
								}
								if("SUCCESS".equals(temp_code)){
									saveTrack(orderNo, "07", "批量执行图片回传成功", status, new Date(), RequestUtil.getLoginUser());
								}else{
									saveTrack(orderNo, "07", temp_msg, status, new Date(), RequestUtil.getLoginUser());
								}
							}
							
						}
					}
				}
				
			}
		} catch (Exception e) {
			try {
				Thread.sleep(50);
			} catch (InterruptedException e1) {
			}
		}
		//组装xlsx文档上传
		String fileParentPath = System.getProperty("user.dir") + File.separator + "pushImg" + File.separator + System.currentTimeMillis();
		String fileName = "救援单图片回传报告";
		// 表名、表头数据
		String title = fileName;
		String[] headers = {"救援单号", "来源单号", "状态", "失败原因"};
		String[] fields = {"orderNo", "ownerOrderNo", "status", "failMsg"};
		String reportUrl = fileParentPath + File.separator + fileName + ".xlsx";
		if (!PublicUtil.isEmpty(records)) {
			try {
				SXSSFWorkbook wb = ExportUtil.createWorkbook(10, false);//创建工作簿对象
				ExportUtil.exportExcel(title, headers, fields, 0, wb, records);
				File fileParent = new File(fileParentPath);
				if (!fileParent.exists()) { // 若目录不存在则创建
					fileParent.mkdirs();
				}
				File file = new File(reportUrl);
				if (file.exists()) { // 若文件已存在则删除
					file.delete();
				}
				try {
					wb.write(new FileOutputStream(file));
				} catch (Exception e) {
					e.printStackTrace();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		//更新回传记录信息
		OrderPushImgEntity vo = new OrderPushImgEntity();
		vo.setDataId(dataId);
		vo.setUpdateTime(new Date());
		vo.setStatus("1");//状态，0-导入中，1-完成
		vo.setSuccessNumber(successNumber.get());
		vo.setFailNumber(failNumber.get());
		vo.setReportUrl(fileParentPath + File.separator + fileName + ".xlsx");
		this.update(vo);
	}

	
	private void saveTrack(String orderNo, String trackType, String trackDesc, String status, Date currentDate, LoginAuthDto loginUser){
        // 服务单轨迹表
        OrderTrackEntity orderTrackEntity = new OrderTrackEntity();
        orderTrackEntity.setDataId(UUID.randomUUID().toString().replace("-", ""));
        orderTrackEntity.setOrderNo(orderNo);
        orderTrackEntity.setTrackType(trackType);
        orderTrackEntity.setTrackDesc(trackDesc);
        orderTrackEntity.setStatus(status);
        orderTrackEntity.setIsDelete(0);
        orderTrackEntity.setCreateTime(currentDate);
        orderTrackEntity.setCreater(loginUser.getUserCode());
        orderTrackEntity.setUpdateTime(currentDate);
        orderTrackEntity.setUpdater(loginUser.getUserCode());
        orderTrackDao.insert(orderTrackEntity);
    }
	/**
	 * DES 加密
	 * */
	public static String DESEncrypt(String content, String key){
		try{
			Cipher cipher = Cipher.getInstance( "DES/CBC/PKCS5Padding");
			cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes(), "DES"), 
					new IvParameterSpec(new byte[]{1,2,3,4,5,6,7,8}));
	        return Base64.getEncoder().encodeToString(cipher.doFinal(content.getBytes("UTF8")));
		}catch(Exception e){
			throw new BusinessException("加密错误");
		}
	}

	/**
	*
	* @author WANGCONG
	* 2022年3月3日下午15:12:36
	* @desc 查询
	*/
	@Override
	public OrderPushImgEntity queryByDataId(String dataId) {
		return orderPushImgDao.queryByDataId(dataId);
	}

}
